package moltencore.network.protocol;

import spark.network.protocol.Base;
import spark.network.protocol.Response;
import spark.network.Util;

public class CreateGameResponse extends Response<CreateGame> {
	private static final Class<CreateGame> REQUEST_TYPE_CLASS = CreateGame.class;

	public static final boolean RELIABLE = false;
	public static final int MESSAGE_LENGTH_MAX = Byte.MAX_VALUE;

	public static final short TYPE = 0x14;
	private static final byte[] TYPE_BYTES = Util.makeBytes(TYPE);

	/**
	 * socket to use for the created game, -1 if creation failed for some reason (if this is the case see message)
	 */
	private int port;
	private static final int PORT_OFFSET = Response.SIZE;
	private static final int PORT_LENGTH = Integer.SIZE / 8;

	/**
	 * Length of the message contained within this package
	 */
	private byte messageLength;
	private static final int MESSAGE_LENGTH_OFFSET = PORT_OFFSET + PORT_LENGTH;
	private static final int MESSAGE_LENGTH_LENGTH = Byte.SIZE / 8;

	/**
	 * Reason for rejection or something else we want to tell the client.
	 */
	private byte[] message;
	private static final int MESSAGE_OFFSET = MESSAGE_LENGTH_OFFSET + MESSAGE_LENGTH_LENGTH;

	private static final int SIZE =
			Response.SIZE +
			PORT_LENGTH +
			MESSAGE_LENGTH_LENGTH;

	public CreateGameResponse() {
		super(RELIABLE, TYPE_BYTES, REQUEST_TYPE_CLASS);
	}

	public CreateGameResponse(CreateGame createGame) {
		super(RELIABLE, TYPE_BYTES, createGame, REQUEST_TYPE_CLASS);
	}

	public void setPort(int port) {
		this.port = port;
	}
	public int getPort() {
		return port;
	}

	public void setGameNotCreated() {
		this.port = -1;
	}

	public boolean gameCreated() {
		return port != -1;
	}

	public byte[] getMessage() {
		return message;
	}

	public void setMessage(String message) {
		byte[] messageBytes = message.getBytes();
		//set the length of the messageLength to the length of the provided string or to the maximal allowed length if the strings
		//length exceeds the maximum length
		messageLength = (byte) ((messageBytes.length > MESSAGE_LENGTH_MAX) ? MESSAGE_LENGTH_MAX : messageBytes.length);

		//write nameLength characters into the name byte array
		this.message = new byte[messageLength];
		System.arraycopy(messageBytes, 0, this.message, 0, messageLength);
	}

	@Override
	public void getBytes(byte[] buffer) {
		super.getBytes(buffer);
		Util.arraycopy(Util.makeBytes(port), 0, buffer, PORT_OFFSET);
		buffer[MESSAGE_LENGTH_OFFSET] = messageLength;
		if(message != null) {
			Util.arraycopy(message, 0, buffer, MESSAGE_OFFSET, messageLength);
		}
	}

	@Override
	public void fill(byte[] buffer) {
		super.fill(buffer);
		port = Util.makeInt(buffer, PORT_OFFSET);
		messageLength = buffer[MESSAGE_LENGTH_OFFSET];
		message = new byte[messageLength];
		Util.arraycopy(buffer, MESSAGE_OFFSET, message, 0, messageLength);
	}

	@Override
	public int getSize() {
		return SIZE + messageLength;
	}

	public static CreateGameResponse create(byte[] buffer, long receiveTime) {
		CreateGameResponse packet = new CreateGameResponse();
		packet.fill(buffer);
		packet.setTimeStampReceive(receiveTime);
		return packet;
	}
}
